package com.example.walled_houses.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.walled_houses.dto.LoginDTO;
import com.example.walled_houses.dto.UserDTO;
import com.example.walled_houses.entity.User;
import com.example.walled_houses.mapper.UserMapper;
import com.example.walled_houses.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.walled_houses.utils.UploadCos;
import com.example.walled_houses.utils.UserHolder;
import com.example.walled_houses.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.example.walled_houses.utils.RedisConstants.LOGIN_USER_KEY;
import static com.example.walled_houses.utils.RedisConstants.LOGIN_USER_TTL;
import static com.example.walled_houses.utils.TengXunConstants.TENGXUN_PATH;
import static com.example.walled_houses.utils.TengXunConstants.TENGXUN_PATHURL;
import static com.example.walled_houses.utils.WechatPatterns.APPID;
import static com.example.walled_houses.utils.WechatPatterns.APP_SECRET;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chengtaoxie
 * @since 2023-10-24
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 用户登录接口
     * @param loginDto
     * @return
     */
    @Override
    @Transactional
    public Result login(LoginDTO loginDto) {
        RestTemplate restTemplate = new RestTemplate();
        String code = loginDto.getCode();
        String nickName = loginDto.getNickName();
        String url = "https://api.weixin.qq.com/sns/jscode2session?" +
                "appid=" + APPID +
                "&secret=" + APP_SECRET +
                "&js_code=" + code +
                "&grant_type=authorization_code";
        String forObject = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONUtil.parseObj(forObject);
        log.info("返回的数据====> {}" + forObject);
        if(StringUtils.contains(forObject, "errcode")){
            return Result.fail().code(201).message("出错了！");
        }
        String openId = jsonObject.getStr("openid");
        String sessionKey = jsonObject.getStr("session_key");
        String unionId = jsonObject.getStr("unionid");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", openId);
        User user = userMapper.selectOne(queryWrapper);
        User user1 = new User();
        user1.setUserId(openId);
        user1.setUserName(nickName);
        user1.setUnionId(unionId);
        if(user != null){
            user.setUserName(nickName);
            userMapper.updateById(user);
        }else {
            userMapper.insert(user1);
        }
        User user2 = userMapper.selectOne(queryWrapper);
        UserDTO userDTO = BeanUtil.copyProperties(user2, UserDTO.class);
        // TODO 将User中的非String类型转化为String类型
//        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
//                CopyOptions.create().setIgnoreNullValue(true).
//                        setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, true, true);
        // TODO 存储
        String key = LOGIN_USER_KEY + sessionKey;
        stringRedisTemplate.opsForHash().putAll(key, userMap);
        // TODO 设置token过期时间
        stringRedisTemplate.expire(key, LOGIN_USER_TTL, TimeUnit.DAYS);
        userDTO.setToken(sessionKey);
        return Result.ok(userDTO);
    }

    /**
     * 获取用户信息
     * @return
     */
    @Override
    public Result getUser() {
        UserDTO userDTO = UserHolder.getUser();
        String userId = userDTO.getUserId();
        User user = userMapper.selectById(userId);
        if(user == null){
            return Result.fail().message("用户不存在！");
        }
        String userPhoto = user.getUserPhoto();
        if(userPhoto != null){
            String url = TENGXUN_PATH + userPhoto;
            user.setUserPhoto(url);
        }
        return Result.ok(user);
    }


    /**
     * 修改用户头像
     * @return
     */
    @Override
    public Result updateUserPhoto(MultipartFile file) {
        UserDTO userDTO = UserHolder.getUser();
        String userId = userDTO.getUserId();
        User user = userMapper.selectById(userId);
        if(user == null){
            return Result.fail().message("用户不存在！");
        }
        Map<Object, String> stringMap = UploadCos.uploadPhoto(file);
        String code = stringMap.get("code");
        if("200".equals(code)){
            String url = stringMap.get("message");
            user.setUserPhoto(url);
            userMapper.updateById(user);
            String userPhoto = user.getUserPhoto();
            if(userPhoto != null){
                UploadCos.deleteCOS(userPhoto);
            }
            return Result.ok(url);
        }else {
            return Result.fail().message("修改失败！");
        }
    }


}
